package com.server.web.controller.common;

import cn.hutool.core.util.ArrayUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.server.common.core.domain.AjaxResult;
import com.server.common.utils.StringUtils;
import com.server.common.utils.SysThreadPool;
import com.server.common.utils.upload.UploadFile;
import com.server.pinggu.domain.SenActionlog;
import com.server.pinggu.domain.SenForms;
import com.server.pinggu.domain.SenUser;
import com.server.pinggu.service.ISenActionlogService;
import com.server.pinggu.service.ISenFormsService;
import com.server.pinggu.service.ISenPgyService;
import com.server.pinggu.service.ISenUserService;
import com.server.pinggu.vo.SenFormsVo;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @Classname FengRui
 * @Description 文件上传
 * @Date 2022-10-24 09:49
 */
@RestController
@Slf4j
@RequestMapping("/public/")
@RequiredArgsConstructor
public class UploadController {

    private final ISenFormsService senFormsService;

    private final ISenPgyService senPgyService;

    private final SysThreadPool sysThreadPool;

    private final ISenActionlogService iSenActionlogService;
    private final ISenUserService iSenUserService;


    @RequestMapping("image/upload")
    public AjaxResult upload(@RequestParam("file") MultipartFile multipartFile)
    {
        return AjaxResult.success("文件上传成功",UploadFile.uploadFile(multipartFile));
    }

//新上传接口 带日志
    @RequestMapping("image/uploadNew")
    public AjaxResult uploadNew(@RequestParam("file") MultipartFile multipartFile,
                                @PathVariable("openId") String openId,@RequestParam("id")Long Id,@RequestParam("str")String Str)
    {
        SenUser one = iSenUserService.getOne(new LambdaQueryWrapper<SenUser>().eq(SenUser::getOopenid, openId));
        String username = one.getUsername();
        iSenActionlogService.save(new SenActionlog(null,one.getId(),username,Id,Str,new Date(System.currentTimeMillis()),null));
        return AjaxResult.success("文件上传成功",UploadFile.uploadFile(multipartFile));
    }
    /**
     * 上传execl  被评估人导入
     */
    @PostMapping("excel/upload")
    public AjaxResult getInfo(@RequestParam("file") MultipartFile multipartFile)
    {
        return AjaxResult.success(senFormsService.lead(multipartFile));
    }

    /**
     * 导出【请填写功能名称】列表
     */
    @PostMapping("pgy/excel/upload")
    public AjaxResult excelUpload(@RequestParam("file") MultipartFile multipartFile)
    {
        return AjaxResult.success(senPgyService.upload(multipartFile));
    }

    /**
     * 导出【请填写功能名称】列表
     */
    @GetMapping("pgy/export")
    public void export(HttpServletRequest request, HttpServletResponse response)
    {
        senPgyService.export(response);
    }

    /**
     * 导出【请填写功能名称】列表
     */
    @GetMapping("pgy/level/export")
    public void export(HttpServletResponse response)
    {
        senPgyService.levelExport(response);
    }


    /**
     * 导出【请填写功能名称】列表
     */
    @PostMapping("forms/sendOrder")
    public AjaxResult sendOrders(@RequestParam("file") MultipartFile multipartFile)
    {
        return AjaxResult.success(senFormsService.sendOrders(multipartFile));
    }

    /**
     * 导出【请填写功能名称】列表
     */
    @PostMapping("forms/updateLevel")
    public AjaxResult updateLevel(@RequestParam("file") MultipartFile multipartFile)
    {
        return AjaxResult.success(senFormsService.updateLevelExcel(multipartFile));
    }


    /**
     * 导出【请填写功能名称】列表
     */
    @GetMapping("forms/Download")
    public void formsDownloadExcel(HttpServletResponse response,SenFormsVo senForms)
    {
        Integer sqsjFront = null;
        Integer sqsjBack = null;
        if (senForms!=null){
            sqsjBack = senForms.getSqsjBack();
            sqsjFront = senForms.getSqsjFront();
        }
        if (StringUtils.isNotEmpty(senForms.getPingnames2())){
            senForms.setPingnames(Arrays.asList(senForms.getPingnames2().split("\\*")));
        }
        senFormsService.formsDownloadExcel(response,senForms,sqsjFront,sqsjBack,senForms.getStatusStr());
    }

    /**
     * 导出【请填写功能名称】列表
     */
    @GetMapping("forms/Download2")
    public void Download2(HttpServletResponse response,SenFormsVo senForms)
    {
        Integer sqsjFront = null;
        Integer sqsjBack = null;
        if (senForms!=null){
            sqsjBack = senForms.getSqsjBack();
            sqsjFront = senForms.getSqsjFront();
        }
        if (StringUtils.isNotEmpty(senForms.getPingnames2())){
            senForms.setPingnames(Arrays.asList(senForms.getPingnames2().split("\\*")));
        }
        senFormsService.formsDownloadExcel2(response,senForms,sqsjFront,sqsjBack,senForms.getStatusStr());
    }


    /**
     * 导出【请填写功能名称】列表
     */
    @PostMapping("forms/132456aasd")
    public void Download2(@RequestParam("url")String url,@RequestParam("renameTo")String renameToUrl)
    {
        long start = System.currentTimeMillis();
        File folder = new File(url);
        File[] listOfFiles = folder.listFiles();
        if (ArrayUtil.isEmpty(listOfFiles)){
            log.info("文件夹为空");
            return;
        }else{
            log.info("文件夹不为空，长度为{}", listOfFiles.length);
        }
        List<File> files = Arrays.asList(listOfFiles);
        List<List<File>> lists = averageAssign(files, 100);
        log.info("List转换成功，长度：{}", lists.size());
        for (List<File> list : lists) {
            sysThreadPool.getAsyncExecutor().execute(() -> {
                for (File file : list) {
                    if (file.isFile()) {
                        boolean a;
                        try {
                            log.info(uploadFile(file, file.getName()));
                            a = true;
                        }catch (Exception e){
                            a= false;
                        }
                        if (a){
                            renameTo(file,renameToUrl);
                        }
                    }
                }
                System.out.println(Thread.currentThread().getName()+",总共上传图片时间"+(System.currentTimeMillis()/1000L-start/1000L));
            });
        }
    }
    public static void renameTo(File file,String url){
        if (file == null || StringUtils.isEmpty(url)){
            return;
        }
        try {
            file.renameTo(new File(url +"/"+ file.getName()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 导出【请填写功能名称】列表
     */
    @GetMapping("forms/download/value")
    public void formsDownloadValueExcel(HttpServletResponse response,@RequestParam("id")Long id)
    {
        senFormsService.formsDownloadValueExcel(response,id);
    }

    @GetMapping("/downloadTemplate")
    public void downloadTemplate(HttpServletResponse response,@RequestParam("url")String url)
    {
        File tempFile = getFile(url);
        try (FileInputStream fis = new FileInputStream(tempFile)) {
            byte[] buffer = new byte[fis.available()];
            int read = fis.read(buffer);
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Length", "" + tempFile.length());
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(tempFile.getName().getBytes()));
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (Exception e) {
            log.error("下载出错-》:{}",e.getMessage());
        }
    }
    private File getFile(String url) {
        //对本地文件命名
        String fileName = url.substring(url.lastIndexOf("."), url.length());
        File file = null;

        URL urlfile;
        try {
            // 创建一个临时路径
            file = File.createTempFile("file", fileName);
            log.info("tempFile:->{}",file.getAbsolutePath());
            //下载
            urlfile = new URL(url);

            try (InputStream inStream = urlfile.openStream();
                 OutputStream os =  new FileOutputStream(file);) {
                int bytesRead = 0;
                byte[] buffer = new byte[8192];
                while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
            }
        } catch (Exception e) {
            log.error("创建临时文件出错：-》{}",e.getMessage());
        }
        return file;
    }


    @RequestMapping("forms/image/upload/file")
    public AjaxResult uploadFile(@RequestParam("file") MultipartFile multipartFile,@RequestParam("id")Long id,@RequestParam("type")String type)
    {
        String url=null;
        if ("image1".equals(type) || "image2".equals(type)|| "image3".equals(type)|| "image4".equals(type)|| "qianzi".equals(type)){
                url= UploadFile.uploadFile(multipartFile);
        }else{
            url= UploadFile.uploadVideo(multipartFile);
        }
        if (StringUtils.isNotEmpty(url)){
            LambdaUpdateWrapper<SenForms> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(SenForms::getId,id);
            if ("image1".equals(type)) {
                lambdaUpdateWrapper.set(SenForms::getImage1,url);
            }else if ("image2".equals(type)){
                lambdaUpdateWrapper.set(SenForms::getImage2,url);
            }else if ("image3".equals(type)){
                lambdaUpdateWrapper.set(SenForms::getImage3,url);
            }else if ("image4".equals(type)){
                lambdaUpdateWrapper.set(SenForms::getImage4,url);
            }else if ("image5".equals(type)){
                lambdaUpdateWrapper.set(SenForms::getImage5,url);
            }else if ("image6".equals(type)){
                lambdaUpdateWrapper.set(SenForms::getImage6,url);
            }else if ("qianzi".equals(type)){
                lambdaUpdateWrapper.set(SenForms::getQianzi,url);
            }
            senFormsService.update(lambdaUpdateWrapper);
        }
        return AjaxResult.success("文件上传成功",url);
    }

    private static String examineUrl="http://pinggu-oss.oss-cn-hangzhou.aliyuncs.com";

    private static String endpoint= "http://oss-cn-hangzhou.aliyuncs.com";

    private static String accessKeyId = "LTAI5tQQcPG1PZHt1rrJ85ca";

    private static String accessKeySecret = "7Lj7dv1a2IIKpyasf9Y0WcxmUokaLH";

    private static String bucketName = "pinggu-oss";

    @SneakyThrows
    public static String uploadFile(File file, String fileName){

        if (file == null){
            throw new RuntimeException("multipartFile cat`t be null");
        }
        String[] split = file.getName().split("\\.");
        if (ArrayUtil.isAllEmpty(split)){
            throw new RuntimeException("fileName cat`t be null");
        }
        String objectName = "Public/uploads/files/"+fileName;
        // 填写本地文件的完整路径，例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, file);
            ossClient.putObject(putObjectRequest);
            return examineUrl+"/"+objectName;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
    private static FileItem getMultipartFile(File file, String fieldName){
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem(fieldName, "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }
    public static <T> List<List<T>> averageAssign(List<T> source, int n) {
        List<List<T>> result = new ArrayList<List<T>>();
        int remaider = source.size() % n;  //(先计算出余数)
        int number = source.size() / n;  //然后是商
        int offset = 0;//偏移量
        for (int i = 0; i < n; i++) {
            List<T> value = null;
            if (remaider > 0) {
                value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
                remaider--;
                offset++;
            } else {
                value = source.subList(i * number + offset, (i + 1) * number + offset);
            }
            result.add(value);
        }
        return result;
    }

}
